package sing.core.base

import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import sing.core.dialog.CustomDialog
import sing.core.ext.dismissLoadingExt
import sing.core.ext.getVmClazz
import sing.core.ext.showLoadingExt
import sing.core.network.manager.NetState
import sing.core.network.manager.NetworkStateManager


/**
 * 描述　: ViewModelFragment基类，自动把ViewModel注入Fragment
 */

abstract class BaseFragment<VM : BaseViewModel,DB : ViewDataBinding>(@LayoutRes private val layoutId: Int, private val viewModelId: Int? = null) : Fragment() {

    private val handler = Handler()

    //是否第一次加载
    private var isFirst: Boolean = true

    lateinit var vm: VM
    fun isVMInitialised() = ::vm.isInitialized

    lateinit var mActivity: AppCompatActivity

    //该类绑定的ViewDataBinding
    lateinit var db: DB
    fun isDBInitialised() = ::db.isInitialized
    private var isNavigationViewInit = false//记录是否已经初始化过一次视图

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        if (!::db.isInitialized){
            db = DataBindingUtil.inflate(inflater, layoutId, container, false)
        }
        db.lifecycleOwner = this
        return db.root
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        mActivity = context as AppCompatActivity
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        if (!isNavigationViewInit){//初始化过视图则不再进行view和data初始化
            super.onViewCreated(view, savedInstanceState)
            isFirst = true
            vm = createViewModel()

            if (viewModelId != null) {
                db.setVariable(viewModelId, vm)
            }

            initView(view,savedInstanceState)
            createObserver()
            registorDefUIChange()
            initData()
            isNavigationViewInit = true
        }
    }

    /**
     * 网络变化监听 子类重写
     */
    open fun onNetworkStateChanged(netState: NetState) {}

    /**
     * 创建viewModel
     */
    private fun createViewModel(): VM {
        return ViewModelProvider(this).get(getVmClazz(this))
    }

    /**
     * 初始化view
     */
    open fun initView(view: View,savedInstanceState: Bundle?) {}
    /**
     * 懒加载
     */
    open fun lazyLoadData(){}

    /**
     * 创建观察者
     */
    open fun createObserver(){}

    override fun onResume() {
        super.onResume()
        onVisible()
    }

    /**
     * 是否需要懒加载
     */
    private fun onVisible() {
        if (lifecycle.currentState == Lifecycle.State.STARTED && isFirst) {
            // 延迟加载 防止 切换动画还没执行完毕时数据就已经加载好了，这时页面会有渲染卡顿
            handler.postDelayed({
                lazyLoadData()
                try {
                    //在Fragment中，只有懒加载过了才能开启网络变化监听
                    NetworkStateManager.instance.mNetworkStateCallback.observeInFragment(this) {
                        if (!isFirst) { //不是首次关注时调用方法，防止数据第一次监听错误
                            onNetworkStateChanged(it)
                        }
                    }
                    isFirst = false
                } catch (e: Exception) {

                }
            }, lazyLoadTime())
        }
    }

    /**
     * Fragment执行onCreate后触发的方法
     */
    open fun initData() {}

    open fun showLoading(message: String = ""){
        showLoadingExt(message)
    }
    open fun dismissLoading(){
        dismissLoadingExt()
    }
    /**
     * 注册 UI 事件
     */
    private fun registorDefUIChange() {
        vm.loadingChange.showDialog.observeInFragment(this) {
            showLoading(it)
        }
        vm.loadingChange.dismissDialog.observeInFragment(this) {
            dismissLoading()
        }
    }

    /**
     * 将非该Fragment绑定的ViewModel添加 loading回调 防止出现请求时不显示 loading 弹窗bug
     * @param viewModels Array<out BaseViewModel>
     */
    protected fun addLoadingObserve(vararg viewModels: BaseViewModel) {
        viewModels.forEach { viewModel ->
            //显示弹窗
            viewModel.loadingChange.showDialog.observeInFragment(this) {
                showLoading(it)
            }
            //关闭弹窗
            viewModel.loadingChange.dismissDialog.observeInFragment(this) {
                dismissLoading()
            }
        }
    }

    /**
     * 延迟加载 防止 切换动画还没执行完毕时数据就已经加载好了，这时页面会有渲染卡顿  bug
     * 这里传入你想要延迟的时间，延迟时间可以设置比转场动画时间长一点 单位： 毫秒
     * 不传默认 300毫秒
     * @return Long
     */
    open fun lazyLoadTime(): Long {
        return 300
    }

    override fun onDestroy() {
        super.onDestroy()
        handler.removeCallbacksAndMessages(null)
    }

    fun showDialog(message: String) {
        val d = CustomDialog(requireContext())
        d.setMsg(message)
        d.hintCancel()
        d.setCancelable(false)
        d.addListener(object : CustomDialog.OnClickListener{
            override fun confirm(dialog: AlertDialog?) {
                super.confirm(dialog)
            }
        })
        d.show()
    }
}